package com.ccp.dev.system.service;

import com.ccp.dev.core.basic.base.BaseService;
import com.ccp.dev.core.basic.util.ContextUtil;
import com.ccp.dev.core.basic.util.UUIDUtils;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.system.consts.FileManagementContants;
import com.ccp.dev.system.dao.FileManagementPermissionDao;
import com.ccp.dev.system.model.FileManagement;
import com.ccp.dev.system.model.FileManagementPermission;
import com.ccp.dev.system.model.SysUser;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 文件管理权限 信息操作服务类
 *
 * @author y
 * @date 2020-03-23 10:52:03
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class FileManagementPermissionService extends BaseService<FileManagementPermission> {

    @Resource
    private FileManagementPermissionDao dao;
    @Resource
    private FileManagementService fileManagementService;
    @Resource
    private RightManageService rightManageService;

    /**
     * 通过id,类型查询权限信息
     *
     * @param permissionType 权限控制的类型1：操作按钮 2：目录节点
     * @param nodeId         目录节点id
     * @return 权限信息
     */
    public List<FileManagementPermission> getPermissionByNodeId(int permissionType, String nodeId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("permissionType", permissionType);
        params.put("nodeId", nodeId);
        return dao.queryPermissionByCondition(params);
    }

    /**
     * 返回某个设置过权限的上级节点的权限
     *
     * @param parentId 父节点id
     * @param treeType 树类型
     */
    public String getParentPermissionByNodeId(String parentId, int treeType) {
        List<FileManagement> list = fileManagementService.queryManageByFileTypeAndTreeType(FileManagementContants.FILE_TYPE_FOLDER, treeType);
        String manageField = "";
        FileManagement parentNode = fileManagementService.getParentNodeWithPermission(parentId, list);
        if (parentNode != null) {
            manageField = parentNode.getManageField();
        }
        return manageField;
    }

    /**
     * 通过json数据找到对应的right
     *
     * @param manageField 权限JSON
     * @param key         JSON里面对应的key
     */
    public String getManageField(String manageField, String key) {
        JSONArray obj = JSONArray.fromObject(manageField);
        JSONObject item = obj.getJSONObject(0);
        JSONObject right = item.getJSONArray("right").getJSONObject(0);
        return right.getString(key);
    }

    /**
     * 保存权限设置
     *
     * @param nodeId         目录节点id
     * @param permissionType 权限控制的类型1：操作按钮 2：目录节点
     * @param manageField    权限JSON信息
     */
    public int addPermission(String nodeId, int permissionType, String manageField) {
        FileManagementPermission permission = new FileManagementPermission();
        SysUser sysUser = (SysUser) ContextUtil.getCurrentUser(); // 获取当前用户
        permission.setId(UUIDUtils.getUUIDFor32());
        permission.setNodeId(nodeId);
        permission.setPermissionType(permissionType);
        permission.setManageField(manageField);
        permission.setOperatorPersonName(sysUser.getAccount());
        permission.setOperatorDate(new Date());
        return dao.add(permission);
    }

    /**
     * 修改权限
     *
     * @param manageField    要更新的权限数据
     * @param permissionType 权限控制的类型1：操作按钮 2：目录节点
     * @param permission     FileManagementPermission对象
     * @return 更新条数
     */
    public int updatePermission(String manageField, int permissionType, FileManagementPermission permission) {
        int updateCount;
        String oldManageField = permission.getManageField();
        permission.setManageField(manageField);
        String operatorPersonName = ContextUtil.getCurrentUser().getAccount();
        permission.setOperatorPersonName(operatorPersonName);
        permission.setOperatorDate(new Date());
        //更新父节点的或者是按钮权限
        updateCount = dao.update(permission);
        //如果是目录授权
        if (permissionType == FileManagementContants.PERMISSION_NODE) {
            String nodeId = permission.getNodeId();
            String newType = getManageField(manageField, "type");
            String oldType = getManageField(oldManageField, "type");
            //查找子孙节点
            List<FileManagement> childFileList = fileManagementService.queryManageByFileTypeAndParentId(FileManagementContants.FILE_TYPE_FOLDER,nodeId);
            if (childFileList.size() > 0) {
                //子孙节点list
                List<FileManagement> retList = new ArrayList<>();
                retList.addAll(childFileList);
                getChildFileList(childFileList,retList);
                List<String> nodeIds = retList.stream().map(FileManagement::getId).collect(Collectors.toList());
                List<FileManagementPermission> list = dao.queryNodesByNodeIds(nodeIds);
                //如果是修改成不同维度，子孙节点直接更新为此父节点的
                if (!newType.equals(oldType) || "everyone".equals(newType) || "none".equals(newType)) {
                    for (FileManagementPermission obj : list) {
                        String childField = obj.getManageField();
                        String updateStr = updateChildRight(manageField, childField);
                        obj.setManageField(updateStr);
                        obj.setOperatorPersonName(operatorPersonName);
                        obj.setOperatorDate(new Date());
                        updateCount += dao.update(obj);
                    }
                } else {
                    String parentIds = getManageField(manageField, "ids");
                    String parentNames = getManageField(manageField, "names");
                    for (FileManagementPermission obj : list) {
                        String childField = obj.getManageField();
                        String names = getManageField(childField, "names");
                        String ids = getManageField(childField, "ids");
                        String newChildIds = setNewToChilds(parentIds, ids);
                        String newChildNames = setNewToChilds(parentNames, names);
                        JSONArray manageFieldObj = JSONArray.fromObject(childField);
                        JSONObject item = manageFieldObj.getJSONObject(0);
                        JSONObject right = item.getJSONArray("right").getJSONObject(0);
                        if (StringUtil.isEmpty(newChildIds)) {
                            //right更新成parent信息
                            String updateStr = updateChildRight(manageField, childField);
                            obj.setManageField(updateStr);
                        } else {
                            right.clear();
                            right.put("type", newType);
                            right.put("names", newChildNames.substring(0, newChildNames.lastIndexOf(",")));
                            right.put("ids", newChildIds.substring(0, newChildIds.lastIndexOf(",")));
                            JSONArray rightArr = new JSONArray();
                            rightArr.add(right);
                            item.put("right", rightArr);
                            obj.setManageField(manageFieldObj.toString());
                        }
                        obj.setOperatorPersonName(operatorPersonName);
                        obj.setOperatorDate(new Date());
                        updateCount += dao.update(obj);
                    }
                }
            }
        }
        return updateCount;
    }

    /**
     * 获取权限数据map
     */
    public Map<String, Boolean> getPermissionMap() {
        Map<String, Object> rightMap = rightManageService.getRightMap(ContextUtil.getCurrentUser().getUserId(), ContextUtil.getCurrentOrgId());

        Map<String, Boolean> managePermission = new HashMap<>();
        List<FileManagementPermission> permissionList = getPermissionByNodeId(FileManagementContants.PERMISSION_BUTTON, FileManagementContants.BUTTON_NODEID);
        if (permissionList.size() > 0) {
            managePermission = rightManageService.getManagePermission(RightManageService.RIGHT_TYPE_MANAGE, permissionList.get(0).getManageField(), rightMap);
        }
        return managePermission;
    }


    /**
     * 查询子孙节点
     */
    private void getChildFileList(List<FileManagement> childFolderList,List<FileManagement> allChild) {
        if (childFolderList.size() > 0) {
            for (FileManagement item : childFolderList) {
                List<FileManagement> childList = fileManagementService.queryManageByFileTypeAndParentId(FileManagementContants.FILE_TYPE_FOLDER,item.getId());
                allChild.addAll(childList);
                getChildFileList(childList,allChild);
            }
        }
    }

    /**
     * 更新子孙节点权限
     */
    private String updateChildRight(String manageField, String childField) {
        JSONArray manageFieldObj = JSONArray.fromObject(childField);
        JSONObject item = manageFieldObj.getJSONObject(0);
        JSONObject childRight = item.getJSONArray("right").getJSONObject(0);
        JSONArray parManageFieldObj = JSONArray.fromObject(manageField);
        JSONObject parItem = parManageFieldObj.getJSONObject(0);
        JSONArray parRight = parItem.getJSONArray("right");
        String parType = parRight.getJSONObject(0).getString("type");
        String childType = childRight.getString("type");
        boolean flag = true;
        //如果上级要设置成everyone，子节点如果是user role org pos其中一个值 是不更新子节点数据的
        if (parType.equals("everyone") && (childType.equals("user") || childType.equals("role") || childType.equals("org") || childType.equals("pos"))) {
            flag = false;
        }
        if (flag) {
            childRight.clear();
            item.put("right", parRight);
        }
        return manageFieldObj.toString();
    }


    /**
     * 同维度的修改之后，更新子孙节点权限为新设置范围内的
     */
    private String setNewToChilds(String parentNames, String childNames) {
        String[] parentArr = parentNames.split(",");
        String[] childArr = childNames.split(",");
        List<String> parentList = Arrays.asList(parentArr);
        List<String> childList = Arrays.asList(childArr);
        String newChild = "";
        for (String childItem : childList) {
            for (String parentItem : parentList) {
                if (childItem.equals(parentItem)) {
                    newChild += childItem + ",";
                }
            }
        }
        return newChild;
    }
}
